package by.myteam.gonki.logic;

import java.awt.event.KeyEvent;

import by.myteam.gonki.bo.CoordinatesObject;
import by.myteam.gonki.bo.Road;
import by.myteam.gonki.bo.car.ICarObject;
import by.myteam.gonki.bo.car.SelectCar;
import by.myteam.gonki.bo.enemy.Enemy;
import by.myteam.gonki.bo.enemy.EnemyFactory;
import by.myteam.gonki.states.mainstate.EGameStates;
import by.myteam.gonki.states.movementstates.MovementStates;

public class GameLogic {
	private MovementStates[] states = MovementStates.values();
	private int road_X = 0;
	private int path = 0;
	private Integer allPath = 0;
	private int speed;
	private int dv = 0;
	private int dy = 0;
	private int health;
	private ICarObject carObject = null;
	private CoordinatesObject carCoordinatObject = null;
	private int travelTime = 0;
	private EnemyFactory enemyFactory = EnemyFactory.INSTANCE;
	public static GameLogic INSTANCE = new GameLogic();

	private GameLogic() {
	}
	
	public void reset(){
		INSTANCE = new GameLogic();
/*		carCoordinatObject = null;
		carObject = null;
		path = 0;
		states = MovementStates.values();
		this.road_X = 0;
		allPath = 0;
		road_X = 0;
		travelTime = 0;
		health = SelectCar.INSTANCE.getCar().getHealth();
		speed = 0;
		dv = 0;
		dy = 0;*/
	}

	public int getDSpeed() {
		return dv;
	}

	public void setDSpeed(int dv) {
		this.dv = dv;
	}

	public int getDy() {
		return dy;
	}

	public void setDy(int dy) {
		this.dy = dy;
	}

	public int getPath() {
		return path;
	}

	public void setPath(int path) {
		this.path = path;
	}

	public int getRoad_X() {
		return road_X;
	}

	public void setRoad_X(int road_X) {
		this.road_X = road_X;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		if (speed <= carObject.getMaxSpeed() && speed >= 0) {
			this.speed = speed;
		} else if (speed > carObject.getMaxSpeed()) {
			this.speed = carObject.getMaxSpeed();
		} else
			this.speed = 0;
	}

	public void setNitro(int speed) {
		this.speed = speed;
	}

	public void move() {
		if (carCoordinatObject != null && carObject != null) {
			if (getHealth() <= 0) {
				EGameStates.GAMEOVER.getState().perform();
				return;
			}
			for (MovementStates state : states) {
				if (state.isPressed()) {
					state.getState().move();
					carCoordinatObject.setY(carCoordinatObject.getY() + dy);
					setSpeed(getSpeed() + dv);
					state.getState().undo();
				}
			}
			if (road_X <= -Road.INSTANCE.getRoadWidth()) {
				road_X = 0;
			}
			road_X -= speed;
			path += getSpeed();
			allPath += getSpeed();
		} else {
			carCoordinatObject = (CoordinatesObject) SelectCar.INSTANCE.getCar();
			carObject = SelectCar.INSTANCE.getCar();
			health = SelectCar.INSTANCE.getCar().getHealth();
		}
	}


	public void checkOnCollision() {
		for (Enemy enemy : enemyFactory.getListEnemy()) {
			if (carObject.getCarWidth() + carCoordinatObject.getX() >= enemy
					.getX()
					&& enemy.getX() >= carCoordinatObject.getX()
					&& carCoordinatObject.getY() >= enemy.getY()
							- carObject.getCarHeigth()
					&& carCoordinatObject.getY() <= enemy.getY()
							+ enemy.getEnemyHeight()) {
				health -= enemy.getDamage();
				setSpeed(getSpeed() - enemy.getSlowdown());
				if (enemy.getVanish()) {
					enemyFactory.getListEnemy().remove(enemy);
				}
				break;
			}
		}
	}

	public void keyPressed(KeyEvent e) {
		for (MovementStates state : states) {
			if (e.getKeyChar() == state.getKey()) {
				state.setPressed(true);
			}
		}

	}

	public void KeyRealeased(KeyEvent e) {
		for (MovementStates state : states) {
			if (e.getKeyChar() == state.getKey()) {
				state.setPressed(false);
			}
		}
	}

	public Integer getAllPath() {
		return allPath;
	}

	public void setAllPath(Integer allPath) {
		this.allPath = allPath;
	}

	public int getTravelTime() {
		return travelTime;
	}

	public void setTravelTime() {
		travelTime++;
	}

	public int getHealth() {
		return health;
	}

	public void setHealth(int health) {
		this.health = health;
	}
}